﻿namespace AssetRipper.IO.Files.SerializedFiles;

[Flags]
public enum TransferMetaFlags : uint
{
	NoTransferFlags = 0x0,
	/// <summary>
	/// Putting this mask in a transfer will make the variable be hidden in the property editor.
	/// </summary>
	HideInEditor = 0x1,
	Unknown1 = 0x2,
	Unknown2 = 0x4,
	Unknown3 = 0x8,
	/// <summary>
	/// Makes a variable not editable in the property editor.
	/// </summary>
	NotEditable = 0x10,
	Unknown5 = 0x20,
	/// <summary>
	/// There are 3 types of PPtrs: <see cref="StrongPPtr"/>, default (weak pointer)
	/// a Strong PPtr forces the referenced object to be cloned.
	/// A Weak PPtr doesnt clone the referenced object, but if the referenced object is being cloned anyway (eg. If another (strong) pptr references this object)
	/// this PPtr will be remapped to the cloned object.
	/// If an object referenced by a WeakPPtr is not cloned, it will stay the same when duplicating and cloning, but be NULLed when templating.
	/// </summary>
	StrongPPtr = 0x40,
	Unknown7 = 0x80,
	/// <summary>
	/// Makes an integer variable appear as a checkbox in the editor.
	/// </summary>
	TreatIntegerValueAsBoolean = 0x100,
	Unknown9 = 0x200,
	Unknown10 = 0x400,
	/// <summary>
	/// Show in simplified editor
	/// </summary>
	SimpleEditor = 0x800,
	/// <summary>
	/// For when the options of a serializer tell you to serialize debug properties (<see cref="TransferInstructionFlags.SerializeDebugProperties"/>).
	/// All debug properties have to be marked <see cref="DebugProperty"/>.
	/// Debug properties are shown in expert mode in the inspector but are not serialized normally.
	/// </summary>
	DebugProperty = 0x1000,
	Unknown13 = 0x2000,
	AlignBytes = 0x4000,
	AnyChildUsesAlignBytes = 0x8000,
	IgnoreWithInspectorUndo = 0x10000,
	Unknown17 = 0x20000,
	EditorDisplaysCharacterMap = 0x40000,
	/// <summary>
	/// Ignore this property when reading or writing .meta files
	/// </summary>
	IgnoreInMetaFiles = 0x80000,
	/// <summary>
	/// When reading meta files and this property is not present, read array entry name instead (for backwards compatibility).
	/// </summary>
	TransferAsArrayEntryNameInMetaFiles = 0x100000,
	/// <summary>
	/// When writing YAML Files, uses the flow mapping style (all properties in one line, with "{}").
	/// </summary>
	TransferUsingFlowMappingStyle = 0x200000,
	/// <summary>
	/// Tells SerializedProperty to generate bitwise difference information for this field.
	/// </summary>
	GenerateBitwiseDifferences = 0x400000,
	DontAnimate = 0x800000,
	TransferHex64 = 0x1000000,
	CharPropertyMask = 0x2000000,
	DontValidateUTF8 = 0x4000000,
	FixedBuffer = 0x8000000,
	DisallowSerializedPropertyModification = 0x10000000,
	Unknown29 = 0x20000000,
	Unknown30 = 0x40000000,
	Unknown31 = 0x80000000,
}

public static class TransferMetaFlagsExtensions
{
	public static bool IsHideInEditor(this TransferMetaFlags _this) => (_this & TransferMetaFlags.HideInEditor) != 0;
	public static bool IsNotEditable(this TransferMetaFlags _this) => (_this & TransferMetaFlags.NotEditable) != 0;
	public static bool IsStrongPPtr(this TransferMetaFlags _this) => (_this & TransferMetaFlags.StrongPPtr) != 0;
	public static bool IsTreatIntegerValueAsBoolean(this TransferMetaFlags _this) => (_this & TransferMetaFlags.TreatIntegerValueAsBoolean) != 0;
	public static bool IsSimpleEditor(this TransferMetaFlags _this) => (_this & TransferMetaFlags.SimpleEditor) != 0;
	public static bool IsDebugProperty(this TransferMetaFlags _this) => (_this & TransferMetaFlags.DebugProperty) != 0;
	public static bool IsAlignBytes(this TransferMetaFlags _this) => (_this & TransferMetaFlags.AlignBytes) != 0;
	public static bool IsAnyChildUsesAlignBytes(this TransferMetaFlags _this) => (_this & TransferMetaFlags.AnyChildUsesAlignBytes) != 0;
	public static bool IsIgnoreWithInspectorUndo(this TransferMetaFlags _this) => (_this & TransferMetaFlags.IgnoreWithInspectorUndo) != 0;
	public static bool IsEditorDisplaysCharacterMap(this TransferMetaFlags _this) => (_this & TransferMetaFlags.EditorDisplaysCharacterMap) != 0;
	public static bool IsIgnoreInMetaFiles(this TransferMetaFlags _this) => (_this & TransferMetaFlags.IgnoreInMetaFiles) != 0;
	public static bool IsTransferAsArrayEntryNameInMetaFiles(this TransferMetaFlags _this) => (_this & TransferMetaFlags.TransferAsArrayEntryNameInMetaFiles) != 0;
	public static bool IsTransferUsingFlowMappingStyle(this TransferMetaFlags _this) => (_this & TransferMetaFlags.TransferUsingFlowMappingStyle) != 0;
	public static bool IsGenerateBitwiseDifferences(this TransferMetaFlags _this) => (_this & TransferMetaFlags.GenerateBitwiseDifferences) != 0;
	public static bool IsDontAnimate(this TransferMetaFlags _this) => (_this & TransferMetaFlags.DontAnimate) != 0;
	public static bool IsTransferHex64(this TransferMetaFlags _this) => (_this & TransferMetaFlags.TransferHex64) != 0;
	public static bool IsCharPropertyMask(this TransferMetaFlags _this) => (_this & TransferMetaFlags.CharPropertyMask) != 0;
	public static bool IsDontValidateUTF8(this TransferMetaFlags _this) => (_this & TransferMetaFlags.DontValidateUTF8) != 0;
	public static bool IsFixedBuffer(this TransferMetaFlags _this) => (_this & TransferMetaFlags.FixedBuffer) != 0;
	public static bool IsDisallowSerializedPropertyModification(this TransferMetaFlags _this) => (_this & TransferMetaFlags.DisallowSerializedPropertyModification) != 0;
	public static IEnumerable<string> Split(this TransferMetaFlags flags)
	{
		if (flags == TransferMetaFlags.NoTransferFlags)
		{
			yield return nameof(TransferMetaFlags.NoTransferFlags);
		}
		else
		{
			if (flags.HasFlag(TransferMetaFlags.HideInEditor))
			{
				yield return nameof(TransferMetaFlags.HideInEditor);
			}

			if (flags.HasFlag(TransferMetaFlags.Unknown1))
			{
				yield return nameof(TransferMetaFlags.Unknown1);
			}

			if (flags.HasFlag(TransferMetaFlags.Unknown2))
			{
				yield return nameof(TransferMetaFlags.Unknown2);
			}

			if (flags.HasFlag(TransferMetaFlags.Unknown3))
			{
				yield return nameof(TransferMetaFlags.Unknown3);
			}

			if (flags.HasFlag(TransferMetaFlags.NotEditable))
			{
				yield return nameof(TransferMetaFlags.NotEditable);
			}

			if (flags.HasFlag(TransferMetaFlags.Unknown5))
			{
				yield return nameof(TransferMetaFlags.Unknown5);
			}

			if (flags.HasFlag(TransferMetaFlags.StrongPPtr))
			{
				yield return nameof(TransferMetaFlags.StrongPPtr);
			}

			if (flags.HasFlag(TransferMetaFlags.Unknown7))
			{
				yield return nameof(TransferMetaFlags.Unknown7);
			}

			if (flags.HasFlag(TransferMetaFlags.TreatIntegerValueAsBoolean))
			{
				yield return nameof(TransferMetaFlags.TreatIntegerValueAsBoolean);
			}

			if (flags.HasFlag(TransferMetaFlags.Unknown9))
			{
				yield return nameof(TransferMetaFlags.Unknown9);
			}

			if (flags.HasFlag(TransferMetaFlags.Unknown10))
			{
				yield return nameof(TransferMetaFlags.Unknown10);
			}

			if (flags.HasFlag(TransferMetaFlags.SimpleEditor))
			{
				yield return nameof(TransferMetaFlags.SimpleEditor);
			}

			if (flags.HasFlag(TransferMetaFlags.DebugProperty))
			{
				yield return nameof(TransferMetaFlags.DebugProperty);
			}

			if (flags.HasFlag(TransferMetaFlags.Unknown13))
			{
				yield return nameof(TransferMetaFlags.Unknown13);
			}

			if (flags.HasFlag(TransferMetaFlags.AlignBytes))
			{
				yield return nameof(TransferMetaFlags.AlignBytes);
			}

			if (flags.HasFlag(TransferMetaFlags.AnyChildUsesAlignBytes))
			{
				yield return nameof(TransferMetaFlags.AnyChildUsesAlignBytes);
			}

			if (flags.HasFlag(TransferMetaFlags.IgnoreWithInspectorUndo))
			{
				yield return nameof(TransferMetaFlags.IgnoreWithInspectorUndo);
			}

			if (flags.HasFlag(TransferMetaFlags.Unknown17))
			{
				yield return nameof(TransferMetaFlags.Unknown17);
			}

			if (flags.HasFlag(TransferMetaFlags.EditorDisplaysCharacterMap))
			{
				yield return nameof(TransferMetaFlags.EditorDisplaysCharacterMap);
			}

			if (flags.HasFlag(TransferMetaFlags.IgnoreInMetaFiles))
			{
				yield return nameof(TransferMetaFlags.IgnoreInMetaFiles);
			}

			if (flags.HasFlag(TransferMetaFlags.TransferAsArrayEntryNameInMetaFiles))
			{
				yield return nameof(TransferMetaFlags.TransferAsArrayEntryNameInMetaFiles);
			}

			if (flags.HasFlag(TransferMetaFlags.TransferUsingFlowMappingStyle))
			{
				yield return nameof(TransferMetaFlags.TransferUsingFlowMappingStyle);
			}

			if (flags.HasFlag(TransferMetaFlags.GenerateBitwiseDifferences))
			{
				yield return nameof(TransferMetaFlags.GenerateBitwiseDifferences);
			}

			if (flags.HasFlag(TransferMetaFlags.DontAnimate))
			{
				yield return nameof(TransferMetaFlags.DontAnimate);
			}

			if (flags.HasFlag(TransferMetaFlags.TransferHex64))
			{
				yield return nameof(TransferMetaFlags.TransferHex64);
			}

			if (flags.HasFlag(TransferMetaFlags.CharPropertyMask))
			{
				yield return nameof(TransferMetaFlags.CharPropertyMask);
			}

			if (flags.HasFlag(TransferMetaFlags.DontValidateUTF8))
			{
				yield return nameof(TransferMetaFlags.DontValidateUTF8);
			}

			if (flags.HasFlag(TransferMetaFlags.FixedBuffer))
			{
				yield return nameof(TransferMetaFlags.FixedBuffer);
			}

			if (flags.HasFlag(TransferMetaFlags.DisallowSerializedPropertyModification))
			{
				yield return nameof(TransferMetaFlags.DisallowSerializedPropertyModification);
			}

			if (flags.HasFlag(TransferMetaFlags.Unknown29))
			{
				yield return nameof(TransferMetaFlags.Unknown29);
			}

			if (flags.HasFlag(TransferMetaFlags.Unknown30))
			{
				yield return nameof(TransferMetaFlags.Unknown30);
			}

			if (flags.HasFlag(TransferMetaFlags.Unknown31))
			{
				yield return nameof(TransferMetaFlags.Unknown31);
			}
		}
	}
}
